#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
//n*(m/B)+m*B>=m*sqrt(n)
constexpr int N(1.5e5+10),M(3e5+10);
using ll=long long;
namespace G
{
	int hd[N],nxt[M<<1],pre[M<<1],tv[M<<1],cnt=1;
	int add_edge(int u,int v)
	{
		int t(++cnt);nxt[t]=hd[u];
		if(hd[u]) pre[hd[u]]=t;
		tv[t]=v;hd[u]=t;return t;
	}
	void del_edge(int u,int t)
	{
		if(!pre[t]) hd[u]=nxt[t];else nxt[pre[t]]=nxt[t];
		if(nxt[t]) pre[nxt[t]]=pre[t];
	}
}
std::vector<int> es[N];
int main()
{
	std::freopen("edge.in","r",stdin);
	std::freopen("edge.out","w",stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int n,m,a,b;std::cin>>n>>m>>a>>b;int B(std::sqrt(n)+1);
	static int deg[N];
	for(int i(1),u,v;i<=m;++i)
	{
		std::cin>>u>>v;
		es[u].push_back(G::add_edge(u,v));
		es[v].push_back(G::add_edge(v,u));
		++deg[u],++deg[v];
	}
	static ll dis[N],db[N];static bool del[N];
	{
		constexpr ll inf(1.01e18);
		std::fill(dis+2,dis+n+1,inf);
		std::fill(db+1,db+n+1,inf);
		std::priority_queue<std::pair<ll,int>,
							std::vector<std::pair<ll,int>>,
							std::greater<std::pair<ll,int>>> pn,pb;
		pn.push({0,1});
		for(int i(1);i<=n;++i)
		{
			while(!pn.empty() && dis[pn.top().second]<pn.top().first) pn.pop();
			while(!pb.empty() && (db[pb.top().second]<pb.top().first || !G::hd[pb.top().second]))
				pb.pop();
			int u;
			if(!pb.empty() && pn.top().first>pb.top().first)
			{
				auto _=pb.top();
				u=G::tv[G::hd[_.second]],dis[u]=_.first;
			}
			else
			{
				u=pn.top().second;pn.pop();
			}
			for(int p:es[u])
			{
				int v(G::tv[p]);
				G::del_edge(v,p^1);
				if(dis[u]+a<dis[v])
				{
					dis[v]=dis[u]+a;
					pn.push({dis[v],v});
				}
				if(dis[u]+b<db[v])
				{
					db[v]=dis[u]+b;
					pb.push({db[v],v});
				}
			}
		}
	}
	for(int i(2);i<=n;++i) std::cout<<dis[i]<<"\n";
	return 0;
}